<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUINode
 *
 * @author jianfeng
 */
abstract class BUINode extends BUIControl {

    const Context_VARIABLE_CURRENTSCREEN = "currentScreen";
    const Context_VARIABLE_CURRENTSCREENFLOW = "currentScreenFlow";

    //put your code here
    protected $space = null;
    protected $sApp = null;
    protected $operation = null;
    protected $style = null;
    protected $menuManager = null;
    protected $bootStrapMenu = null;
    protected $menu = null;
    public $ContextScopeName = 'UINode';
    protected $node = null;
    public $viewPath = null;
    public $formPath = null;
    public $screenPath = null;
    public $screenflowPath = null;
    public $widgetPath = null;
    public $modelPath = null;
    public $uiControlPath = null;
    protected $currentScreen = null;
    protected $currentScreenFlow = null;
    protected $activeScreen = null;
    protected $activeScreenFlow = null;
    protected $startScreenFlow = null;
    protected $startScreen = null;
    public $uiPath = null;
    protected $theme = null;

    public function __construct($node = NULL) {
        parent::__construct();
        $this->node = $node;
    }

    /**
     * 
     * @param type $data
     * @return BNode
     */
    public function getNode($data = NULL) {
        return $this->node;
    }

    public function setNode($node) {
        $this->node = $node;
    }

    public function setTheme($theme) {
        if ($theme != NULL) {
            $this->theme = $theme;            
        }
    }  

    public function getTheme() {

        if ($this->theme != NULL)
            return $this->theme;
    }

    public function getId() {
        $id = '';

        if ($this->node != NULL) {
            $class = get_class($this->node);
            $name = strtolower($class);
            $id = 'ui_' . $name . '_' . $this->node->getId();
        }

        if ($id == "")
            return '000';

        return $id;
    }

    public function getName($data = NULL) {
        if ($this->getNode() instanceof BNode)
            return $this->getNode()->getName();
        else {
            return parent::getName($data);
        }
    }

    //   public abstract function getUrl($data = NULL);

    public function addScreenActionGroup($name, $screenAction) {

        $screenActionStack = $this->getContextVariable('screenActionStack');

        if ($screenActionStack == NULL) {
            $screenActionStack = array();
        }

        if (!isset($screenActionStack[$name]) || $screenActionStack[$name] == NULL) {
            $screenActionStack[$name] = array();
        }

        array_push($screenActionStack[$name], $screenAction);

        $this->addContextVariable('screenActionStack', $screenActionStack);
    }

    public function getScreenActionGroup($name) {
        $screenActionStack = $this->getContextVariable('screenActionStack');
        return $screenActionStack[$name];
    }

    public function addContextVariable($name, $value, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getContextObj();

        //if ($name == BContextObj::VariableName_Id)
        //return $tObj->addContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentNodeId, $value);

        return $tObj->addContextVariable(BContextObj::Scope_CurrentUINode, $name, $value);
    }

    public function getContextVariable($name, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getContextObj();
        /*
          $currentNode = $tObj->getContextVariable(BContextObj::Scope_Application, BContextObj::VariableName_CurrentNode);

          if ($name == BContextObj::VariableName_Id) {
          //return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentNodeId);
          $currentNode = $tObj->getContextVariable($scope, $name);
          }

          if ($name === BContextObj::V_CurrentScreenId)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenId);
          if ($name === BContextObj::V_CurrentScreenClass)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenClass);
          if ($name === BContextObj::V_CurrentScreenFlowId)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowId);
          if ($name === BContextObj::V_CurrentScreenFlowClass)
          return $tObj->getContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentScreenFlowClass);
         * 
         */

        return $tObj->getContextVariable(BContextObj::Scope_CurrentUINode, $name);

        //return FALSE;       
    }

    public function resetContextVariable($scope = NULL, $name = NULL) {
        if ($scope == NULL)
            $scope = BContextObj::Scope_CurrentUINode;
        //only when uinode changed, reset Context variables
        $tObj = Blyn::app()->getContextObj();
        if ($name == NULL) {
            $tId = $this->getContextVariable(BContextObj::Current_Id);
            $myId = $this->getId();
            if ($tId != $myId) {
                $tObj->resetContextVariable($scope);
                //$tObj->resetContextVariable(BContextObj::Scope_AppMeta);
                $this->addContextVariable(BContextObj::Current_Id, $myId);
            }
        } else {
            //if (name == BContextObj::VariableName_Id)
            //return $tObj->resetContextVariable(BContextObj::Scope_AppMeta, BContextObj::V_CurrentNodeId);
            $tObj->resetContextVariable($scope, $name);
        }
    }

    public function resetNode($data = array()) {
     
    }

    public function getUINodeFilesPath($type = 'viewPath') {

        $viewPath = FALSE;
        $formPath = FALSE;

        $node = Blyn::app()->getCurrentNode();

        if ($node instanceof BOperation || $node instanceof BApp) {
            $viewPath = Blyn::app()->getActiveApp()->getUIManager()->viewPath;
            $formPath = Blyn::app()->getActiveApp()->getUIManager()->formPath;
        }

        if ($viewPath == FALSE) {
            $viewPath = Blyn::app()->getUIManager()->viewPath;
        }

        if ($formPath == FALSE) {
            $formPath = Blyn::app()->getUIManager()->formPath;
        }

        if ($type == 'formPath')
            return $formPath;

        return $viewPath;
    }

    /**
     * 
     * @return BUIScreen
     */
    public function getCurrentScreen() {

        $currentScreen = NULL;

        if ($this->currentScreen == NULL) {
            $currentScreen = Blyn::app()->getCurrentNode()->getContextVariable(BContextObj::VariableName_CurrentScreen);

            if ($currentScreen != NULL)
                $this->currentScreen = $this->getScreen($currentScreen);
        }

        if ($this->currentScreenFlow instanceof BUIScreenFlow) {
            $screen = $this->currentScreenFlow->current();
            if ($screen instanceof BUIScreen)
                $this->currentScreen = $screen;
        }

        if ($this->currentScreen == NULL && $this->getStartScreen() != NULL)
            $this->currentScreen = $this->getStartScreen();

        if ($this->currentScreen == NULL)
            $this->currentScreen = new BUIScreen('default_screen');

        return $this->currentScreen;
    }

    public function getCurrentScreenFlow() {
        /**
         * if currentScreenFlow is null, can init it by checking Context variable
         * maybe this screenflow has been continued by last same screenflow 
         */
        if ($this->currentScreenFlow == NULL) {
            $flow = Blyn::app()->getCurrentNode()->getContextVariable(BContextObj::VariableName_CurrentScreenFlow);
            if ($flow == NULL)
                $flow = $this->getStartScreenFlow() == NULL ? NULL : $this->getStartScreenFlow();
            if ($flow != NULL) {
                //$this->currentScreenFlow = is_array($flow) ? key($flow) : $flow;
                $this->currentScreenFlow = $flow;
                if (is_string($this->currentScreenFlow)) {
                    $this->currentScreenFlow = $this->getScreenFlow($this->currentScreenFlow);
                }

                if ($this->currentScreenFlow instanceof BUIScreenFlow) {
                    $flowIndex = Blyn::app()->getCurrentNode()->getContextVariable(BUIScreenFlow::CONTEXT_VARIABLE_SCREENFLOW_INDEX);
                    //$flowIndex = $flow[BUIScreenFlow::ContextVARIABLE_SCREENFLOW_INDEX];
                    $flowIndex = is_numeric($flowIndex) ? $flowIndex : 0;
                    $this->currentScreenFlow->setIndex($flowIndex);
                }
            }
        }

        if ($this->currentScreenFlow == NULL)
            $this->currentScreenFlow = new BUIScreenFlow('default_screenflow');

        return $this->currentScreenFlow;
    }

    public function setCurrentScreenFlow($screenFlow) {
        $this->currentScreenFlow = $screenFlow;

        /**
         * reset screenflow means if currentscreen flow changed, should empty variables for currentscreenflow
         * and ready for new variables of new current screenflow 
         */
        if ($this->currentScreenFlow instanceof BUIScreenFlow) {
            //$screenFlow->resetContextVariable();
            $this->currentScreenFlow->setNode($this->getNode());
        }
    }

    public function setCurrentScreen($screen) {
        $this->currentScreen = $screen;
        if ($this->currentScreen instanceof BUIScreen)
            $this->currentScreen->setNode($this->getNode());

        //if currentScreen is not member of screenflow, means not active screenflow
        //if ($screen instanceof BUIScreen && !$screen->isMemberOfScreenFlow())
        // $this->setCurrentScreenFlow(FALSE);
        //$screen->resetContextVariables();
    }

    public function getScreen($name) {

        //if screen is currentscreen, return it
        if ($this->currentScreen instanceof BUIScreen) {
            if ($this->currentScreen->getName() == $name)
                return $this->currentScreen;
        }

        if (is_string($name))
            $screen = new $name();

        if (is_array($name)) {
            $screenData = $name;
            $screenClass = 'BUIScreen';
            if (isset($screenData['class'])) {
                $className = $screenData['class'];
                if (class_exists($className))
                    $screenClass = $className;
            }
            $screen = $screenClass->load($screenData);
        }

        if ($name instanceof BConfig) {
            $screenConfig = $name;
            $screenClass = 'BUIScreen';

            if ($screenConfig->getConfigValue('class') != NULL) {
                $className = $screenConfig->getConfigValue('class');
                if (class_exists($className))
                    $screenClass = $className;
            }
            $screen = $screenClass->load($screenConfig);
        }

        if ($name instanceof BUIScreen)
            $screen = $name;

        $screen->setNode($this->getNode());

        return $screen;
    }

    public function getScreenFlow($config) {

        $screenFlow = NULL;

        //if screen is currentscreen, return it
        if (is_string($config)) {
            $name = $config;
            if ($this->currentScreenFlow instanceof BUIScreenFlow) {
                if ($this->currentScreenFlow->getName() == $name)
                    return $this->currentScreenFlow;
            }
            else {
                $className = 'BUIScreenFlow';
                if (class_exists($name))
                    $className = $name;
                $screenFlow = new $className;
            }
        }

        if (is_array($config)) {
            $screenFlowData = $config;
            $screenFlowClass = 'BUIScreenFlow';
            if (isset($screenFlowData['class'])) {
                $className = $screenFlowData['class'];
                if (class_exists($className))
                    $screenFlowClass = $className;
            }
            $screenFlow = new $screenFlowClass();
            $screenFlow->load($screenFlowData);
        }

        if ($config instanceof BConfig) {
            $screenFlowConfig = $config;
            $screenFlowClass = 'BUIScreenFlow';

            if ($screenFlowConfig->getConfigValue('class') != NULL) {
                $className = $screenFlowConfig->getConfigValue('class');
                if (class_exists($className))
                    $screenFlowClass = $className;
            }
            $screenFlow = new $screenFlowClass();
            $screenFlow->load($screenFlowConfig);
        }

        if ($config instanceof BUIScreenFlow)
            $screenFlow = $config;

        if ($screenFlow instanceof BUIScreenFlow) {
            $screenFlow->setNode($this->getNode());
            return $screenFlow;
        }
        return FALSE;
    }

    public function getStartScreen($data = NULL) {
        return NULL;
    }

    public function getStartScreenFlow($data = NULL) {
        return NULL;
    }

    public function getAjaxContainerId($data = NULL) {
        if ($this instanceof BUIBlyn)
            return BUIBase::ajaxContainter_application;
        if ($this instanceof BUISpace)
            return BUIBase::ajaxContainter_Space;
        if ($this instanceof BUIApp)
            return BUIBase::ajaxContainter_App;
        if ($this instanceof BUIOperationFlow)
            return BUIBase::ajaxContainer_operationFlow;
        if ($this instanceof BUIOperation)
            return BUIBase::ajaxContainter_operation;
    }

}

?>
